<template>
  <q-scroll-area ref="scroller" style="height: 100%; width: 100%; z-index: 0">
    <div ref="container" class="container column">
      <div ref="upper" class="col upper" @click="onDoubleClick">
        <q-menu ref="popupMenu" touch-position auto-close>
          <q-input
            v-model="currentPopupLine"
            autofocus
            dense
            @keyup.enter="addNewCaption"
          >
            <template v-slot:append>
              <q-btn
                dense
                icon="mdi-plus"
                v-close-popup
                @click="addNewCaption"
              ></q-btn>
            </template>
          </q-input>
        </q-menu>
      </div>
      <div ref="lower" class="lower"></div>
      <div ref="blocks" class="blocks">
        <TextBlock
          :ref="setBlockRefs"
          v-for="(caption, index) in captionList"
          :key="index"
          v-bind="caption"
          :zoom="zoom"
          :scale="scale"
          @update:start="onBlockStartUpdate($event, caption)"
          @update:duration="onBlockDurationUpdate($event, caption)"
          @update:text="onBlockTextUpdate($event, caption)"
          @delete="onBlockDelete(caption)"
          @click="select(index)"
        />
      </div>
    </div>
  </q-scroll-area>
</template>
<script setup lang="ts">
import { computed, ref, onMounted, watch } from 'vue';
import TextBlock from './blocks/TextBlock.vue';
import { QMenu, QScrollArea, throttle } from 'quasar';
import VTTBuilder from 'src/utils/VTTBuilder';
import useUndoRedo from 'src/mixins/UndoRedo';
import StudioOperate, { OperateType } from 'src/models/StudioOperate';
import { useVideoStore } from 'src/stores/video-store';
import { useCaptionStroe } from 'stores/caption-store';
import { storeToRefs } from 'pinia';
import Caption from 'src/models/Caption';
const videoStore = useVideoStore();
const captionStore = useCaptionStroe();
const { captionList } = storeToRefs(captionStore);
const { videoElement } = storeToRefs(videoStore);
const currentTime = computed<number>(() => videoStore.currentTime);
let vttBuilder: VTTBuilder | null = null;
const props = defineProps({
  duration: {
    type: Number,
    default: 0,
  },
  zoom: {
    type: Number,
    default: 1,
  },
  scroll: {
    type: Boolean,
    default: false,
  },
  scrollPosition: {
    type: Number,
    default: 0,
  },
  handle: {
    type: Boolean,
    default: false,
  },
  isRecording: {
    type: Boolean,
    default: false,
  },
});
const emit = defineEmits(['select']);
const container = ref<HTMLDivElement>();
const scroller = ref<QScrollArea>();
const blocks = ref<HTMLDivElement>();
const currentPopupLine = ref('');
const popupMenu = ref<QMenu>();
const { addAction } = useUndoRedo();
let blockRefs: any[] = [];
let scale = ref(0);
let clientWidth = 0;
let clientHeight = 0;
let width = ref(0);
watch(
  () => props.duration,
  () => {
    update();
  }
);
watch(
  () => props.zoom,
  () => {
    update();
  }
);
watch(
  () => props.scrollPosition,
  () => {
    if (scroller.value) {
      scroller.value?.setScrollPosition('horizontal', props.scrollPosition);
    }
  }
);
watch(videoElement, () => {
  if (videoElement.value) {
    captionStore.newCaption(videoElement.value);
  }
});
function setBlockRefs(el: any) {
  if (el) {
    if (blockRefs.indexOf(el) === -1) {
      blockRefs.push(el);
    }
  }
}
onMounted(() => {
  clientWidth = container.value!.parentElement!.clientWidth;
  clientHeight = container.value!.clientHeight;
  update();
});
function update() {
  clientWidth = container.value!.parentElement!.clientWidth;
  clientHeight = container.value!.clientHeight;
  scale.value = clientWidth / props.duration;
  width.value = scale.value * props.duration * props.zoom;
  if (container.value) {
    container.value.style.width = `${width.value}px`;
  }
}
function addCaption(
  text: string,
  start = currentTime.value,
  duration = 5,
  flag = true,
  cueId?: string
) {
  captionStore.addCaption(start, duration, text);
}
function addNewCaption() {
  addCaption(currentPopupLine.value, clickPosition);
  currentPopupLine.value = '';
  popupMenu.value?.hide();
}
let clickPosition = 0;
function onDoubleClick(event: MouseEvent) {
  clickPosition = px2time(event.offsetX);
  deselect();
}
const blockStartUpdate = throttle(function (value: number, caption: Caption) {
  captionStore.updateStartTime(caption, value);
}, 60);
function onBlockStartUpdate(value: number, caption: Caption) {
  blockStartUpdate(value, caption);
}
const blockDurationUpdate = throttle(function (
  value: number,
  caption: Caption
) {
  captionStore.updateDuration(caption, value);
},
60);
function onBlockDurationUpdate(value: number, caption: Caption) {
  blockDurationUpdate(value, caption);
}
const blockTextUpdate = throttle(function (value: string, caption: Caption) {
  captionStore.updateText(caption, value);
}, 60);
function onBlockTextUpdate(value: string, caption: Caption) {
  blockTextUpdate(value, caption);
}
function getCaptionList() {
  return captionList.value;
}
function restore(blocksInfo: any[]) {
  blocksInfo.forEach((info) => {
    addCaption(info.text, info.start, info.duration);
  });
}
function px2time(px: number) {
  return px / (scale.value * props.zoom);
}
function onBlockDelete(caption: Caption) {
  captionStore.removeCaption(caption);
}
function select(index: number) {
  console.log(index);
  if (blockRefs.length > 0) {
    deselect();
    blockRefs[index].select();
    emit('select', index);
  }
}
function deselect() {
  if (blockRefs.length > 0) {
    blockRefs.forEach((block) => {
      block.unselect();
    });
    emit('select', null);
  }
}
function split(index: number) {
  const caption = captionList.value[index];
  captionStore.splitCaption(caption, videoStore.currentTime);
}
defineExpose({
  addCaption,
  getCaptionList,
  restore,
  split,
});
</script>
<style lang="sass" scoped>

.container
  z-index: 0
  overflow-y: hidden
  position: absolute
  height: 100%
  .recording
    width: 100%
    height: 100%
    position: absolute
    background-color: rgba(299,55,72,0.1)
  .blocks
    height: 100%
    position: absolute
    top: 0
    left: 0
  .lower
    height: 25px
    background-color: #161616
    z-index: 0
</style>
